<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>canvas星空</title>

<style>

body {
  width: 100%;
  height: 100%;
  background: linear-gradient(to right, rgba(252, 161, 132, 1),  rgba(251, 215, 134, 1));
  color: rgba(2,0,0,0.87);
  
canvas {
  position: fixed;
  width: 100%;
  height: 100%;
}



.a:hover {
  color: #fff;
}
.button {
    background-color: #4CAF50; /* Green */
    border: none;
    color: white;
    padding: 15px 32px;
    text-align: center;
    text-decoration: none;
    display: inline-block;
    font-size: 16px;
    margin: 4px 2px;
    cursor: pointer;
    background-color:green;
}
</style>


</head>
<body>
	<div style="position: fixed;top: 0;left:0;bottom: 0;right: 0;z-index: 0">
    <canvas id="canvas" style="background: linear-gradient(to right, rgba(252, 161, 132, 1),  rgba(251, 215, 134, 1));"></canvas>
  </div>


<script type="text/javascript">
  const canvas = document.getElementById('canvas')
  const ctx = canvas.getContext('2d')
  let width = window.innerWidth
  let height = window.innerHeight
 
  let dotsNum = 40 // 点的数量
  let radius = 0.5 // 圆的半径，连接线宽度的一半
  let fillStyle = 'rgba(255,255,255,0.5)' // 点的颜色
  let lineWidth = radius * 2
  let connection = 120 // 连线最大距离
  let followLength = 80 // 鼠标跟随距离
 
  let dots = []
  let animationFrame = null
  let mouseX = null
  let mouseY = null
 
  function addCanvasSize () { // 改变画布尺寸
    width = window.innerWidth
    height = window.innerHeight
    canvas.width = width
    canvas.height = height
    ctx.clearRect(0, 0, width, height)
    dots = []
    if (animationFrame) window.cancelAnimationFrame(animationFrame)
    initDots(dotsNum)
    moveDots()
  }
 
  function mouseMove (e) {
    mouseX = e.clientX
    mouseY = e.clientY
  }
 
  function mouseOut (e) {
    mouseX = null
    mouseY = null
  }
 
  function mouseClick () {
    for (const dot of dots) dot.elastic()
  }
 
  class Dot {
    constructor(x, y) {
      this.x = x
      this.y = y
      this.speedX = Math.random() * 2 - 1
      this.speedY = Math.random() * 2 - 1
      this.follow = false
    }
    draw () {
      ctx.beginPath()
      ctx.arc(this.x, this.y, radius, 0, 2 * Math.PI)
      ctx.fill()
      ctx.closePath()
    }
    move () {
      if (this.x >= width || this.x <= 0) this.speedX = -this.speedX
      if (this.y >= height || this.y <= 0) this.speedY = -this.speedY
      this.x += this.speedX
      this.y += this.speedY
      if (this.speedX >= 1) this.speedX--
      if (this.speedX <= -1) this.speedX++
      if (this.speedY >= 1) this.speedY--
      if (this.speedY <= -1) this.speedY++
      this.correct()
      this.connectMouse()
      this.draw()
    }
    correct () { // 根据鼠标的位置修正
      if (!mouseX || !mouseY) return
      let lengthX = mouseX - this.x
      let lengthY = mouseY - this.y
      const distance = Math.sqrt(lengthX ** 2 + lengthY ** 2)
      if (distance <= followLength) this.follow = true
      else if (this.follow === true && distance > followLength && distance <= followLength + 8) {
        let proportion = followLength / distance
        lengthX *= proportion
        lengthY *= proportion
        this.x = mouseX - lengthX
        this.y = mouseY - lengthY
      } else this.follow = false
    }
    connectMouse () { // 点与鼠标连线
      if (mouseX && mouseY) {
        let lengthX = mouseX - this.x
        let lengthY = mouseY - this.y
        const distance = Math.sqrt(lengthX ** 2 + lengthY ** 2)
        if (distance <= connection) {
          opacity = (1 - distance / connection) * 0.5
          ctx.strokeStyle = `rgba(255,255,255,${opacity})`
          ctx.beginPath()
          ctx.moveTo(this.x, this.y)
          ctx.lineTo(mouseX, mouseY);
          ctx.stroke();
          ctx.closePath()
        }
      }
    }
    elastic () { // 鼠标点击后的弹射
      let lengthX = mouseX - this.x
      let lengthY = mouseY - this.y
      const distance = Math.sqrt(lengthX ** 2 + lengthY ** 2)
      if (distance >= connection) return
      const rate = 1 - distance / connection // 距离越小此值约接近1
      this.speedX = 40 * rate * -lengthX / distance
      this.speedY = 40 * rate * -lengthY / distance
    }
  }
 
  function initDots (num) { // 初始化粒子
    ctx.fillStyle = fillStyle
    ctx.lineWidth = lineWidth
    for (let i = 0; i < num; i++) {
      const x = Math.floor(Math.random() * width)
      const y = Math.floor(Math.random() * height)
      const dot = new Dot(x, y)
      dot.draw()
      dots.push(dot)
    }
  }
 
  function moveDots () { // 移动并建立点与点之间的连接线
    ctx.clearRect(0, 0, width, height)
    for (const dot of dots) {
      dot.move()
    }
    for (let i = 0; i < dots.length; i++) {
      for (let j = i; j < dots.length; j++) {
        const distance = Math.sqrt((dots[i].x - dots[j].x) ** 2 + (dots[i].y - dots[j].y) ** 2)
        if (distance <= connection) {
          opacity = (1 - distance / connection) * 0.5
          ctx.strokeStyle = `rgba(255,255,255,${opacity})`
          ctx.beginPath()
          ctx.moveTo(dots[i].x, dots[i].y)
          ctx.lineTo(dots[j].x, dots[j].y);
          ctx.stroke();
          ctx.closePath()
        }
      }
    }
    animationFrame = window.requestAnimationFrame(moveDots)
  }
 
  addCanvasSize()
 
  initDots(dotsNum)
  moveDots()
 
  document.onmousemove = mouseMove
  document.onmouseout = mouseOut
  document.onclick = mouseClick
  window.onresize = addCanvasSize

</script>
	
<div style="color:white;position: absolute; top:45%;left:550px; font:normal 34px/44px 'MicroSoft YaHei';margin:0 auto；">主题：教育经费及收入差距对教育需求造成的影响

<a style="color:#392d6c;font:normal 34px/44px 'MicroSoft YaHei';" href="{{url_for('index')}}">开始探索</a>
</div>
	
</body>
</html>